package com.asa.chart.work;

import java.awt.EventQueue;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import com.asa.chart.Transform2D;
import com.asa.chart.Transform3D22D;
import com.asa.chart.base.Line;
import com.asa.chart.base.Point;

/**
 * 封装mvc
 * 
 * @author Administrator
 *
 */
public class Algo3DVisualizer {

	private AlgoFrame frame;

	public static Calendar c;
	private long startTime;
	public static long midTime;

	private boolean createsoldier = false;
	private boolean createsoldier_blue = false;

	private boolean showAxles = true;
	private boolean show2DAxles = false;// 这个测试用的

	private List<String> textzhi;
	private List<double[]> textpointzhi;

	public Algo3DVisualizer(final int sceneWidth, final int sceneHeight, int N, List<double[][]> zhi, int zoom,
			List<String> textzhi, List<double[]> textpointzhi, boolean showAxles) {
		super();
		this.showAxles = showAxles;
		this.textzhi = textzhi;
		this.textpointzhi = textpointzhi;

		init(sceneWidth, sceneHeight, N, zhi, zoom);
		c = Calendar.getInstance();
		startTime = c.getTimeInMillis();
		EventQueue.invokeLater(new Runnable() {// 用java事件分发（开了个线程）的方法来创建对话框

			public void run() {
				// TODO Auto-generated method stub
				frame = new AlgoFrame("wellcome", sceneWidth, sceneHeight);
				frame.addKeyListener(new AlgoKeyListener());
				frame.addMouseListener(new AlgoMouseListener());
				new Thread(new Runnable() {

					public void run() {
						// TODO Auto-generated method stub
						runmiage();
					}

				}).start();
				;

			}
		});

	}

	public Algo3DVisualizer(final int sceneWidth, final int sceneHeight, int N, List<double[][]> zhi, int zoom,
			boolean showAxles) {
		super();
		this.showAxles = showAxles;

		init(sceneWidth, sceneHeight, N, zhi, zoom);
		c = Calendar.getInstance();
		startTime = c.getTimeInMillis();
		EventQueue.invokeLater(new Runnable() {// 用java事件分发（开了个线程）的方法来创建对话框

			public void run() {
				// TODO Auto-generated method stub
				frame = new AlgoFrame("wellcome", sceneWidth, sceneHeight);
				frame.addKeyListener(new AlgoKeyListener());
				frame.addMouseListener(new AlgoMouseListener());
				new Thread(new Runnable() {

					public void run() {
						// TODO Auto-generated method stub
						runmiage();
					}

				}).start();
				;

			}
		});

	}

	public Algo3DVisualizer(final int sceneWidth, final int sceneHeight, int N, List<double[][]> zhi, int zoom) {
		super();

		init(sceneWidth, sceneHeight, N, zhi, zoom);
		c = Calendar.getInstance();
		startTime = c.getTimeInMillis();

		EventQueue.invokeLater(new Runnable() {// 用java事件分发（开了个线程）的方法来创建对话框

			public void run() {
				// TODO Auto-generated method stub
				frame = new AlgoFrame("wellcome", sceneWidth, sceneHeight);
				frame.addKeyListener(new AlgoKeyListener());
				frame.addMouseListener(new AlgoMouseListener());
				new Thread(new Runnable() {

					public void run() {
						// TODO Auto-generated method stub
						runmiage();
					}

				}).start();
				;

			}
		});

	}

	List<Line> mapline;
	List<List<Line>> canves;

	List<String> text;
	List<Point> textpoint;

	int zoom;

	private void init(final int sceneWidth, final int sceneHeight, int N, List<double[][]> zhi, int zoom) {

		mapline = new ArrayList<Line>();
		List<double[][]> xyzAxles = new ArrayList<double[][]>();
		if (text == null) {
			text = new ArrayList<String>();
		}
		if (textpoint == null) {
			textpoint = new ArrayList<Point>();
		}
		double[] point0 = { 10, 10, 10 };// 平面上的一个点
		double[] n_fa = { 1, 1, 1 };// 平面的法向量
		List<double[][]> zhi_transform = new ArrayList<double[][]>();

		if (show2DAxles) {
			System.out.println(show2DAxles);
			// 画y轴
			{
				Point spoint = new Point();
				Point epoint = new Point();
				spoint.x = sceneWidth / 2;
				spoint.y = 0;
				epoint.x = sceneWidth / 2;
				epoint.y = sceneHeight;
				Line line = new Line();
				line.spoint = spoint;
				line.epoint = epoint;
				mapline.add(line);
			}

			// 画x轴
			{
				Point spoint = new Point();
				Point epoint = new Point();
				spoint.x = 0;
				spoint.y = sceneHeight / 2;
				epoint.x = sceneWidth;
				epoint.y = sceneHeight / 2;
				Line line = new Line();
				line.spoint = spoint;
				line.epoint = epoint;
				mapline.add(line);
			}

			// 画辅助线
			for (int i = 0; i <= sceneHeight / (zoom * 2); i++) {
				Point spoint = new Point();
				Point epoint = new Point();
				spoint.x = sceneWidth / 2 - 5;
				spoint.y = sceneHeight / 2 - i * zoom;
				epoint.x = sceneWidth / 2 + 5;
				epoint.y = sceneHeight / 2 - i * zoom;
				Line line = new Line();
				line.spoint = spoint;
				line.epoint = epoint;
				mapline.add(line);

				Point spoint2 = new Point();
				Point epoint2 = new Point();
				spoint2.x = sceneWidth / 2 - 5;
				spoint2.y = sceneHeight / 2 + i * zoom;
				epoint2.x = sceneWidth / 2 + 5;
				epoint2.y = sceneHeight / 2 + i * zoom;
				Line line2 = new Line();
				line2.spoint = spoint2;
				line2.epoint = epoint2;
				mapline.add(line2);

				text.add("" + i);
				textpoint.add(line.spoint);

				if (i == 0) {
					continue;
				}

				text.add("-" + i);
				textpoint.add(line2.spoint);
			}

			for (int i = 0; i <= sceneWidth / (zoom * 2); i++) {

				Point spoint = new Point();
				Point epoint = new Point();
				spoint.x = sceneWidth / 2 + i * zoom;
				spoint.y = sceneHeight / 2 - 5;
				epoint.x = sceneWidth / 2 + i * zoom;
				epoint.y = sceneHeight / 2 + 5;
				Line line = new Line();
				line.spoint = spoint;
				line.epoint = epoint;
				mapline.add(line);

				Point spoint2 = new Point();
				Point epoint2 = new Point();
				spoint2.x = sceneWidth / 2 - i * zoom;
				spoint2.y = sceneHeight / 2 - 5;
				epoint2.x = sceneWidth / 2 - i * zoom;
				epoint2.y = sceneHeight / 2 + 5;
				Line line2 = new Line();
				line2.spoint = spoint2;
				line2.epoint = epoint2;
				mapline.add(line2);

				text.add("" + i);
				textpoint.add(line.spoint);
				if (i == 0) {
					continue;
				}
				text.add("-" + i);
				textpoint.add(line2.spoint);

			}
		}
		// 三维坐标画出来

		{
			List<double[][]> zhi3D = new ArrayList<double[][]>();
			double zhouchang = 20.0;// 每条坐标轴的长度

			double[] xyz_o = { 0.0, 0.0, 0.0 };// 原点
			double[] xyz_x = { zhouchang, 0.0, 0.0 };// 轴x
			double[] xyz_y = { 0.0, zhouchang, 0.0 };// 轴y
			double[] xyz_z = { 0.0, 0.0, zhouchang };// 轴z

			double[] xy_o = Transform3D22D.point3topoint2(xyz_o, n_fa, point0);

			double[] xy_x = Transform3D22D.point3topoint2(xyz_x, n_fa, point0);
			double[] xy_y = Transform3D22D.point3topoint2(xyz_y, n_fa, point0);
			double[] xy_z = Transform3D22D.point3topoint2(xyz_z, n_fa, point0);

//				System.out.println(xy_o[0]+"    "+xy_o[1] +"	 "+xy_o[2]);

//				x=(x1-x2)cosθ-(y1-y2)sinθ+x2
//				y=(y1-y2)cosθ+(x1-x2)sinθ+y2
			// 我的心有点累，先对坐标点进行补丁式的修正吧，应该是z轴的旋转有问题，少旋转了一个60度
			double rotate = Math.PI / 3;

			xy_x = Transform2D.rotate(xy_x, xy_o, rotate);
			xy_y = Transform2D.rotate(xy_y, xy_o, rotate);
			xy_z = Transform2D.rotate(xy_z, xy_o, rotate);

			double[][] tensor_x = { { xy_o[0], xy_o[1] }, { xy_x[0], xy_x[1] } };
			double[][] tensor_y = { { xy_o[0], xy_o[1] }, { xy_y[0], xy_y[1] } };
			double[][] tensor_z = { { xy_o[0], xy_o[1] }, { xy_z[0], xy_z[1] } };
			zhi3D.add(tensor_x);
			zhi3D.add(tensor_y);
			zhi3D.add(tensor_z);

//				for (int i = 0; i < tensor_z.length; i++) {
//					for (int j = 0; j < tensor_z.length; j++) {
//						System.out.print(tensor_z[i][j]+ "  xix  " );
//					}
//					System.out.println();
//				}

			List<String> text = new ArrayList<String>();
			List<double[]> textpoint = new ArrayList<double[]>();

			// 画坐标轴的箭头
			// 画z轴的箭头
			double rotate_archer1 = Math.PI / 4;
			double rotate_archer2 = -rotate_archer1;
			List<double[][]> zhi_archer = new ArrayList<double[][]>();

			for (int i = 0; i < zhi3D.size(); i++) {
				double[][] line2archer = zhi3D.get(i);
				double asa_x = line2archer[0][0];
				double asa_y = line2archer[0][1];

				double x2 = line2archer[1][0];
				double y2 = line2archer[1][1];

				{

					double[] xy1_1 = { asa_x, asa_y };
					double[] xy1_2 = { x2, y2 };
					double[] rotate_point1 = Transform2D.rotate(xy1_1, xy1_2, rotate_archer1);

					double[] midpoint1 = Transform2D.midpoint(rotate_point1, xy1_2);
					midpoint1 = Transform2D.midpoint(midpoint1, xy1_2);
					midpoint1 = Transform2D.midpoint(midpoint1, xy1_2);
					midpoint1 = Transform2D.midpoint(midpoint1, xy1_2);
					double[][] archer_z1 = { { line2archer[1][0], line2archer[1][1] }, { midpoint1[0], midpoint1[1] } };
					zhi_archer.add(archer_z1);
				}

				{
					double[] xy2_1 = { asa_x, asa_y };
					double[] xy2_2 = { x2, y2 };
					double[] rotate_point2 = Transform2D.rotate(xy2_1, xy2_2, rotate_archer2);
					double[] midpoint2 = Transform2D.midpoint(rotate_point2, xy2_2);
					midpoint2 = Transform2D.midpoint(midpoint2, xy2_2);
					midpoint2 = Transform2D.midpoint(midpoint2, xy2_2);
					midpoint2 = Transform2D.midpoint(midpoint2, xy2_2);
					double[][] archer_z2 = { { line2archer[1][0], line2archer[1][1] }, { midpoint2[0], midpoint2[1] } };
					zhi_archer.add(archer_z2);

				}

			}

			List<double[][]> zhi_kedu = new ArrayList<double[][]>();

			double kedu = 2.0;
			int keshu = (int) (zhouchang / 2);

			// 画坐标轴上面的刻度
			for (int i = 1; i < keshu; i++) {
				double[] xyz_x_kedu1 = { kedu * i, 0.0, 0.0 };
				double[] xyz_x_kedu2 = { kedu * i, 0.0, 0.5 };
				double[] xy_x_kedu1 = Transform3D22D.point3topoint2(xyz_x_kedu1, n_fa, point0);
				double[] xy_x_kedu2 = Transform3D22D.point3topoint2(xyz_x_kedu2, n_fa, point0);
				xy_x_kedu1 = Transform2D.rotate(xy_x_kedu1, xy_o, rotate);
				xy_x_kedu2 = Transform2D.rotate(xy_x_kedu2, xy_o, rotate);
				double[][] xy_x_kedu = new double[2][];
				xy_x_kedu[0] = xy_x_kedu1;
				xy_x_kedu[1] = xy_x_kedu2;
				zhi_kedu.add(xy_x_kedu);

				text.add("" + kedu * i);
				double[] point = { xy_x_kedu1[0], xy_x_kedu1[1] };
				textpoint.add(point);
			}

			for (int i = 1; i < keshu; i++) {
				double[] xyz_y_kedu1 = { 0.0, kedu * i, 0.0 };
				double[] xyz_y_kedu2 = { 0.0, kedu * i, 1.0 };
				double[] xy_y_kedu1 = Transform3D22D.point3topoint2(xyz_y_kedu1, n_fa, point0);
				double[] xy_y_kedu2 = Transform3D22D.point3topoint2(xyz_y_kedu2, n_fa, point0);
				xy_y_kedu1 = Transform2D.rotate(xy_y_kedu1, xy_o, rotate);
				xy_y_kedu2 = Transform2D.rotate(xy_y_kedu2, xy_o, rotate);
				double[][] xy_y_kedu = new double[2][];
				xy_y_kedu[0] = xy_y_kedu1;
				xy_y_kedu[1] = xy_y_kedu2;
				zhi_kedu.add(xy_y_kedu);

				text.add("" + kedu * i);
				double[] point = { xy_y_kedu1[0], xy_y_kedu1[1] };
				textpoint.add(point);
			}

			for (int i = 1; i < keshu; i++) {
				double[] xyz_z_kedu1 = { 0.0, 0.0, kedu * i };
				double[] xyz_z_kedu2 = { 1.0, 0.0, kedu * i };
				double[] xy_z_kedu1 = Transform3D22D.point3topoint2(xyz_z_kedu1, n_fa, point0);
				double[] xy_z_kedu2 = Transform3D22D.point3topoint2(xyz_z_kedu2, n_fa, point0);
				xy_z_kedu1 = Transform2D.rotate(xy_z_kedu1, xy_o, rotate);
				xy_z_kedu2 = Transform2D.rotate(xy_z_kedu2, xy_o, rotate);
				double[][] xy_z_kedu = new double[2][];
				xy_z_kedu[0] = xy_z_kedu1;
				xy_z_kedu[1] = xy_z_kedu2;
				zhi_kedu.add(xy_z_kedu);

				text.add("" + kedu * i);
				double[] point = { xy_z_kedu1[0], xy_z_kedu1[1] };
				textpoint.add(point);
			}

			zhi3D.addAll(zhi_archer);
			zhi3D.addAll(zhi_kedu);

			xyzAxles.addAll(zhi3D);
			this.textzhi = text;
			this.textpointzhi = textpoint;

			for (int i = 0; i < zhi.size(); i++) {
				double[][] xyz = zhi.get(i);// 获取点

				double[][] e = new double[xyz.length][];
				for (int j = 0; j < xyz.length; j++) {
					double[] asa = xyz[j];
					System.out.println(asa.length);

					System.out.println(asa[0] + "  " + asa[1]);
					double[] point3topoint2 = Transform3D22D.point3topoint2(asa, n_fa, point0);

					e[j] = Transform2D.rotate(point3topoint2, xy_o, rotate);

				}

				zhi_transform.add(e);
			}

		}
		

		canves = new ArrayList<List<Line>>();
		
		
		
		if (showAxles) {//是否画出三维坐标轴
			if (textzhi != null) {
				for (int i = 0; i < textzhi.size(); i++) {
					double[] pointzhi = textpointzhi.get(i);

					Point point = new Point();
					point.x = (int) (reverse_x(pointzhi[0] * zoom, sceneWidth));
					point.y = (int) (reverse_y(pointzhi[1] * zoom, sceneHeight));

					textpoint.add(point);
					text.add(textzhi.get(i));

				}
			}
			
			for (int i = 0; i < xyzAxles.size(); i++) {

				double[][] ds = xyzAxles.get(i);
				List<Line> canve = new ArrayList<Line>();

				for (int j = 0; j < ds.length - 1; j++) {

					double x1 = ds[j][0];
					double y1 = ds[j][1];
					double x2 = ds[j + 1][0];
					double y2 = ds[j + 1][1];

					Point spoint = new Point();
					Point epoint = new Point();
					spoint.x = (int) (reverse_x(x1 * zoom, sceneWidth));
					spoint.y = (int) (reverse_y(y1 * zoom, sceneHeight));
					epoint.x = (int) (reverse_x(x2 * zoom, sceneWidth));
					epoint.y = (int) (reverse_y(y2 * zoom, sceneHeight));

//				spoint.x = (int) (x1*10);
//				spoint.y = (int) (y1*10);
//				epoint.x = (int) (x2*10);
//				epoint.y = (int) (y2*10);

					Line line = new Line();
					line.spoint = spoint;
					line.epoint = epoint;

					canve.add(line);

				}

				canves.add(canve);

			}

		}
		for (int i = 0; i < zhi_transform.size(); i++) {

			double[][] ds = zhi_transform.get(i);
			List<Line> canve = new ArrayList<Line>();

			for (int j = 0; j < ds.length - 1; j++) {

				double x1 = ds[j][0];
				double y1 = ds[j][1];
				double x2 = ds[j + 1][0];
				double y2 = ds[j + 1][1];

				Point spoint = new Point();
				Point epoint = new Point();
				spoint.x = (int) (reverse_x(x1 * zoom, sceneWidth));
				spoint.y = (int) (reverse_y(y1 * zoom, sceneHeight));
				epoint.x = (int) (reverse_x(x2 * zoom, sceneWidth));
				epoint.y = (int) (reverse_y(y2 * zoom, sceneHeight));

//				spoint.x = (int) (x1*10);
//				spoint.y = (int) (y1*10);
//				epoint.x = (int) (x2*10);
//				epoint.y = (int) (y2*10);

				Line line = new Line();
				line.spoint = spoint;
				line.epoint = epoint;

				canve.add(line);

			}
			canves.add(canve);

		}

	}

	public double reverse_x(double x, int w) {

		return x + w / 2;

	}

	public double reverse_y(double y, int h) {
		return -y + h / 2;
	}

	private void runmiage() {
		while (true) {

			AlgoVisHelper.pause(20);
			// 更新数据

			frame.render(mapline, canves, text, textpoint);

			c = Calendar.getInstance();

		}
	}

	boolean isAnimated;

	private class AlgoKeyListener extends KeyAdapter {

		@Override
		public void keyReleased(KeyEvent event) {
			// TODO Auto-generated method stub
			super.keyReleased(event);
			if (event.getKeyChar() == ' ') {
				isAnimated = !isAnimated;
			}

		}

	}

	private class AlgoMouseListener extends MouseAdapter {

		@Override
		public void mousePressed(MouseEvent event) {
			// TODO Auto-generated method stub

			event.translatePoint(0, -(frame.getBounds().height - frame.getCanvasHeight()));

			java.awt.Point point = event.getPoint();
			System.out.println(point);
			int x = point.x;
			int y = point.y;

			int index = x / 100;
			int indey = y / 100;

			System.out.println(index);
			System.out.println(indey);

		}

	}

}
